package com.yuke.cloud.service.omc.controller.frontend;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.yuke.cloud.common.base.constant.MQConstants;
import com.yuke.cloud.common.base.dto.MsgNotificationBody;
import com.yuke.cloud.common.core.mq.RabbitMetaMessage;
import com.yuke.cloud.common.core.mq.RabbitSender;
import com.yuke.cloud.common.util.BigDecimalUtil;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.common.util.wrapper.WrapMapper;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.cmc.dto.CmsCouponUserDto;
import com.yuke.cloud.service.api.cmc.service.CmcFeignApi;
import com.yuke.cloud.service.api.opc.service.OpcSendNotifyFeignApi;
import com.yuke.cloud.service.api.smc.dto.ShopInfoDto;
import com.yuke.cloud.service.api.smc.service.SmcFeignApi;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.omc.entity.OdsOrder;
import com.yuke.cloud.service.omc.entity.OdsPayOrder;
import com.yuke.cloud.service.omc.entity.OdsStockGoods;
import com.yuke.cloud.service.omc.entity.OdsStockOrder;
import com.yuke.cloud.service.omc.payUtil.Alipayutil;
import com.yuke.cloud.service.omc.payUtil.payutil;
import com.yuke.cloud.service.omc.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;


/**
 * 创建时间：2016年11月2日 下午4:16:32
 * 参考文档 https://docs.open.alipay.com/204/105301/
 * https://docs.open.alipay.com/204/105051
 *
 * @author andy
 * @version 2.2
 */
@RestController
@RequestMapping("/order")
@Import(RabbitSender.class)
@Slf4j
public class PayController {
    @Resource
    private OdsOrderService odsOrderService;
    @Resource
    private OdsOrderGoodsService odsOrderGoodsService;
    @Autowired
    private RabbitSender rabbitSender;
    @Resource
    private OdsPayOrderService odsPayOrderService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SmcFeignApi smcFeignApi;
    @Autowired
    private CmcFeignApi cmcFeignApi;

    @Autowired
    private WmcStorageFeignApi wmcStorageFeignApi;
    @Resource
    private OdsStockGoodsService odsStockGoodsService;
    @Resource
    private OdsStockOrderService odsStockOrderService;
    @Autowired
    private OpcSendNotifyFeignApi opcSendNotifyFeignApi;
    @Autowired
    private OdsBillService odsBillService;

    @Value("${yuke.alipay.callback.url}")
    private String alipayNotify;
    private static final Logger LOG = Logger.getLogger(PayController.class);

    /**
     * app支付下订单
     *
     * @param
     * @param
     * @param //mercid   商品id
     * @param //callback
     * @param// cashnum
     * 支付金额
     */


    @RequestMapping(value = "/alipay", method = RequestMethod.POST)
    public Wrapper orderPay(@RequestBody JSONObject json) {
        System.out.println("进入支付接口");
        LOG.info("参数json={}");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        String pay_order_ids = json.get("pay_order_ids").toString();
        String totalpay = json.get("totalpay").toString();
        String paytype = json.get("paytype").toString();
        AlipayTradeAppPayRequest request1 = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        if (paytype.equals("normal")) {
            model.setBody("normal");//订单描述
        } else if (paytype.equals("shopnosend")) {
            model.setBody("shopnosend");
        } else if (paytype.equals("shopsend")) {
            model.setBody("shopsend");
        }

        // add by wg 20190328 如果订单重新提交，则只更新订单表，不用新生成订单
        Long getsnowid = null;
        OdsPayOrder payOrder = new OdsPayOrder();
        payOrder.setOrderIds(pay_order_ids);
        List<OdsPayOrder> listPayOrder = odsPayOrderService.select(payOrder);
        if (listPayOrder != null && listPayOrder.size() > 0) {
            getsnowid = listPayOrder.get(0).getPayId();
        }

        model.setSubject("裕客网支付交易");//商品标题，交易标题
        //用雪花算法生成分布式id
        if (getsnowid == null) {
            getsnowid = odsOrderService.getsnowid();
        }

        String s = String.valueOf(getsnowid);
        model.setOutTradeNo(s);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(totalpay);
        model.setProductCode("QUICK_MSECURITY_PAY");
        request1.setBizModel(model);
        request1.setNotifyUrl(alipayNotify);
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response1 = Alipayutil.getAlipayClient().sdkExecute(request1);
            //就是orderString 可以直接给客户端请求，无需再做处理。
            String re = response1.getBody();
            System.err.println(re);
            //同时生成支付表，支付表关联包含的订单ids
            OdsPayOrder odsPayOrder = new OdsPayOrder();
            //out_trade_no就是payorder的id；
            odsPayOrder.setPayId(getsnowid);
            odsPayOrder.setOrderIds(pay_order_ids);
            if (listPayOrder != null && listPayOrder.size() > 0) {
                odsPayOrderService.update(odsPayOrder);
            } else {
                // 如果已经存在过订单集合，则重新支付时是每个订单单独支付，此时应删除掉原有的订单集合
                odsPayOrderService.deleteByOrderIds(pay_order_ids);

                odsPayOrderService.save(odsPayOrder);
            }

            return WrapMapper.ok(re);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param
     * @param
     * @param ，查询
     * @param
     * @param
     */
    @RequestMapping(value = "/pay/query", method = RequestMethod.POST)
    public Wrapper orderPayQuery(JSONObject jsonObject) {
        LOG.info("[/order/pay/query]");
      /*  if (StringUtil.isEmpty(tradeno) && StringUtil.isEmpty(orderno)) {
            WebUtil.response(response, WebUtil.packJsonp(callback, JSON
                    .toJSONString(new JsonResult(-1, "订单号不能为空", new ResponseData()), SerializerFeatureUtil.FEATURES)));
        }
*/
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest(); // 统一收单线下交易查询
        // 只需要传入业务参数
        Object out_trade_no = jsonObject.get("out_trade_no");
        Map<String, Object> param = new HashMap<>();
        param.put("out_trade_no", out_trade_no); // 商户订单号
        param.put("trade_no", "");//支付宝交易号。一定要写，即使为空
        alipayRequest.setBizContent(JSON.toJSONString(param)); // 不需要对json字符串转义
        Map<String, String> restmap = new HashMap<String, String>();// 返回提交支付宝订单交易查询信息
        boolean flag = false; // 查询状态
        try {
            //每次都实例化客户端吗

            AlipayTradeQueryResponse alipayResponse = Alipayutil.getAlipayClient().execute(alipayRequest);
            if (alipayResponse.isSuccess()) {
                // 调用成功，则处理业务逻辑
                if ("10000".equals(alipayResponse.getCode())) {
                    // 订单创建成功
                    flag = true;
                    restmap.put("order_no", alipayResponse.getOutTradeNo());
                    restmap.put("trade_no", alipayResponse.getTradeNo());
                    restmap.put("buyer_logon_id", alipayResponse.getBuyerLogonId());
                    restmap.put("trade_status", alipayResponse.getTradeStatus());
                    LOG.info("订单查询结果：" + alipayResponse.getTradeStatus());
                } else {
                    LOG.info("订单查询失败：" + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (flag) {
            return WrapMapper.ok(restmap);
        } else { // 订单查询失败
            return WrapMapper.ok("失败");
        }
    }


    @RequestMapping(value = "/pay/notify", method = RequestMethod.POST)
    public String orderPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        LOG.info("[/order/pay/notify],收到支付宝反馈过来的信息");
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        System.out.println("支付宝回调函数："+requestParams);
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
             params.put(name, valueStr);
        }
        //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_typ
        // 验签看是不是支付宝发过来的信息，防止网络攻击
        System.out.println(params);
        log.info("支付宝回调，{}", params);
        try {

            boolean flag = AlipaySignature.rsaCheckV1(params, Alipayutil.ALIPAY_PUBLIC_KEY, "utf-8", "RSA2");
            if (flag) {
                Boolean bSuccess = false;  // 交易是否成功
                String tradeStatus = params.get("trade_status");
                if (tradeStatus != null && (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED"))) {
                    bSuccess = true;
                }


                String s = params.get("refund_fee");
                if (bSuccess && s != null) {

                    log.info("收到支付宝的退款成功反馈");
                    return "success";
                }

                if (!bSuccess) {
                    if (s != null) {
                        log.info("支付宝的退款失败反馈");
                    }else {
                        log.info("支付宝的支付失败反馈");
                    }

                    return "success";
                }

                log.info("支付宝的支付成功反馈");  // add for debug 20190322
                OdsPayOrder ods = odsPayOrderService.findById(Long.valueOf(params.get("out_trade_no")));
                String total_amount = params.get("total_amount");  // 支付宝接口返回总付款，单位元
                String orderIds = ods.getOrderIds();
                String[] split = orderIds.split(",");

                double dTotalAmount = Double.parseDouble(total_amount);
                double iTotalAmount = BigDecimalUtil.mul(dTotalAmount, 100).doubleValue();
                ods.setAmountPaid((int)iTotalAmount);
                odsPayOrderService.update(ods);
                System.out.println("参数params="+params.get("body"));
                if (params.get("body").equals("shopnosend")) {
                    System.out.println("shopnosend");
                    /**店铺购买
                     * 划拨
                     * **/
                    redisTemplate.delete("second:" + split[0]);
                    OdsStockOrder odsStockOrder = new OdsStockOrder();
                    odsStockOrder.setStockOrderId(Long.valueOf(split[0]));
                    odsStockOrder.setPayTime(new Date());
                    odsStockOrder.setPayStatus((byte) 1);
                    double v = Double.parseDouble(total_amount);
                    // mod by wg 20190413
                    // double v1 = v * 100;
                    double v1 = BigDecimalUtil.mul(v, 100).doubleValue();
                    odsStockOrder.setAmountPaid((int) v1);
                    odsStockOrder.setStockStatus((byte) 1);//1已确认表示没有发货，已完成表示已经入库
                    odsStockOrderService.update(odsStockOrder);
                    //todo 调用feign接口划拨对应商店的仓库地址
                    OdsStockGoods odsStockGoods = new OdsStockGoods();
                    System.out.println(Long.valueOf(split[0]));
                    odsStockGoods.setStockOrderId(Long.valueOf(split[0]));
                    List<OdsStockGoods> select = odsStockGoodsService.select(odsStockGoods);
                    OdsStockGoods byId1 = select.get(0);
                    Date inboundPlanTime = byId1.getInboundPlanTime();
                    if (inboundPlanTime != null && inboundPlanTime.getDay() == new Date().getDay()) {
                        List<Map> list = new ArrayList<Map>();
                        List<Long> list1 = new ArrayList<>();
                        Long shopid = null;
                        for (int i = 0; i < select.size(); i++) {
                            Map map = new HashMap();
                            OdsStockGoods odsStockGoods1 = select.get(i);
                            if (System.currentTimeMillis() >= odsStockGoods1.getInboundPlanTime().getTime()) {
                                System.out.println("时间比较吗");
                                Long orderId = odsStockGoods1.getStockOrderId();
                                OdsStockOrder byId = odsStockOrderService.findById(orderId);
                                Long shopId = byId.getShopId();
                                shopid = shopId;
                                Long specId = odsStockGoods1.getSpecId();
                                Integer goodsNum = odsStockGoods1.getStockNumber();
                                list1.add(odsStockGoods1.getStockGoodsId());
                                map.put("shopId", shopId);
                                map.put("specId", specId);
                                //已经付款，总仓库数量不变，店铺下面的商品变多
                                map.put("goodsNum", goodsNum);
                                list.add(map);
                            }
                        }
                        String ss = JSON.toJSONString(list);
                        System.err.println(ss);
                        smcFeignApi.updateStockCount(ss);
                        //添加具体入库时间
                        for (int i = 0; i < list1.size(); i++) {
                            OdsStockGoods odsStockGoods1 = new OdsStockGoods();
                            odsStockGoods1.setStockGoodsId(list1.get(i));
                            odsStockGoods1.setInboundTime(new Date());
                            odsStockGoods1.setGoodsStatus((byte)1);
                            odsStockGoodsService.update(odsStockGoods1);
                        }
                        MsgNotificationBody msg = new MsgNotificationBody();
                        msg.setTitle("发货通知");
                        msg.setContent("您的进货订单" + split[0] + "已经划拨发货");
                        msg.setTime(new Date());
                        msg.setReceiveType((byte) 3);
                        msg.setOrderType((byte) 1);
                        msg.setMsgType("orderMsg");
                        List<Long> list2 = new ArrayList<>();
                        list2.add(shopid);
                        Long userId = smcFeignApi.getShopUserIdByShopIds(list2).get(0).getUserId();
                        opcSendNotifyFeignApi.sendnotify(userId.toString(), "发货通知", "您的进货订单" + split[0] + "已经发货", 0);
                        opcSendNotifyFeignApi.sendnotify(userId.toString(), "发货通知", JSON.toJSONString(msg), 1);
                    }
                } else {
                    StringBuilder sb = new StringBuilder();
                    // mod by wg 20190516
                    if (params.get("body").equals("normal")) {
                        // add by wg 20190516 保存店铺信息
                        List<Long> shopIds = new ArrayList<>();
                        // add by wg 20190516 保存订单信息
                        List<OdsOrder> odsOrders = new ArrayList<>();
                        for (int i = 0; i < split.length; i++) {
                            OdsOrder byId2 = odsOrderService.findById(Long.valueOf(split[i]));

                            // add by wg 20190711 增加货到付款处理
                            if (byId2.getPayType() != 0) {
                               redisTemplate.delete("zero:" + split[i]);
                               //20191026 解决redis first键没被删除的问题
                               if (byId2.getOrderType().equals((byte)2)){
                                   redisTemplate.delete("first:" + split[i]);
                               }


                            }
                            //如果此单使用了优惠券，标记使用状态
                            if (null != byId2 && null != byId2.getCouponReceiveId()
                                    &&  null != byId2.getCouponMoney()){
                                System.out.println("如果此单使用了优惠券，标记使用状态");
                                cmcFeignApi.updateCouponReceive(Long.valueOf(byId2.getCouponReceiveId()),Long.valueOf(split[i]));
                            }

                            //todo 第一删除redis里面的key，第二修改订单的状态
                            OdsOrder odsOrder = new OdsOrder();
                            odsOrder.setOrderId(Long.valueOf(split[i]));
                            odsOrder.setPayStatus((byte) 1);
                           // odsOrder.setPayType((byte)2);  // add by wg 20190711
                            odsOrder.setPayTime(new Date());

                            // add by wg 20190711 增加货到付款处理
                            if (byId2.getPayType() == 0) {  // 货到付款
                                odsOrder.setShippingStatus((byte) 3);
                                odsOrder.setOrderStatus((byte) 1);
                            } else {
                                //odsOrder.setShippingStatus((byte) 0);
                                odsOrder.setOrderStatus((byte) 1);
                            }

                            if (byId2 != null) {
                                odsOrder.setAmountPaid(byId2.getAmountPayable());
                            } else {
                                double v = Double.parseDouble(total_amount);
                                // mod by wg 20190413
                                // double v1 = v * 100;
                                double v1 = BigDecimalUtil.mul(v, 100).doubleValue();
                                odsOrder.setAmountPaid((int) v1);
                            }


                            //保存到数据库，修改订单状态为已付款，未发货
                            odsOrderService.update(odsOrder);



                            // add by wg 20190711 增加货到付款处理
                            if (byId2.getPayType() != 0) {
                                String a = String.valueOf(byId2.getShopId());
                                if (i == split.length - 1) {
                                    sb.append(a);
                                } else {
                                    sb.append(a + ",");
                                }

                                shopIds.add(byId2.getShopId());
                                if (byId2.getIsFactory()) {
                                    shopIds.add(byId2.getFactoryShopId());
                                }
                                odsOrders.add(byId2);
                            }
                        }

                        // add by wg 20190711 增加货到付款处理
                        if (odsOrders.size() > 0) {
                            // mod by wg 20190516 V1.1版，如果配送类型是同城发送时，直接通知仓库发货，或者配送类型是仓库配送的即时达类型也由仓库发货
                            // 获取店铺信息
                            List<ShopInfoDto> shopInfoDtos = smcFeignApi.getShopInfoByShopIds(shopIds);
                            for (OdsOrder odsOrder : odsOrders) {
                                if (odsOrder.getShippingType() == 0) {  // 同城即时达
                                    for (ShopInfoDto shopInfoDto : shopInfoDtos) {
                                        if (odsOrder.getShopId().equals(shopInfoDto.getShopId()) && shopInfoDto.getShopType() == 1) {  // 店铺类型为云顶店铺
                                            MsgNotificationBody msg = new MsgNotificationBody();
                                            msg.setTitle("订单处理");
                                            msg.setContent("您的店铺有订单需要处理");
                                            msg.setTime(new Date());
                                            msg.setReceiveType((byte) 3);
                                            msg.setOrderType((byte) 1);
                                            msg.setMsgType("orderMsg");
                                            Long userId = shopInfoDto.getUserId();
                                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", "您的店铺有订单需要处理", 0);
                                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", JSON.toJSONString(msg), 1);

                                            break;
                                        } else if (odsOrder.getShopId().equals(shopInfoDto.getShopId()) && shopInfoDto.getShopType() == 4) {  // 直营店铺
                                            //同时通知仓库(用rabbitmq发送)，有新订单需要打印
                                            //同时通知仓库(用rabbitmq发送)，有新订单需要打印
                                            sendMsgToWarehouse(odsOrder.getShopId().toString(), null);
                                        }
                                    }
                                } else if (odsOrder.getIsFactory()) {  // 厂家直销订单，直接通知厂家发货
                                    for (ShopInfoDto shopInfoDto : shopInfoDtos) {
                                        if (odsOrder.getFactoryShopId().equals(shopInfoDto.getShopId()) && shopInfoDto.getShopType() == 3) {  // 店铺类型为云顶店铺
                                            MsgNotificationBody msg = new MsgNotificationBody();
                                            msg.setTitle("订单处理");
                                            msg.setContent("您有订单需要发货");
                                            msg.setTime(new Date());
                                            msg.setReceiveType((byte) 3);
                                            msg.setOrderType((byte) 1);
                                            msg.setMsgType("orderMsg");
                                            Long userId = shopInfoDto.getUserId();
                                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", "您有订单需要发货", 0);
                                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", JSON.toJSONString(msg), 1);

                                            break;
                                        }
                                    }
                                } else if (odsOrder.getShippingType() == 2) { // 同城快送
                                    //同时通知仓库(用rabbitmq发送)，有新订单需要打印
                                    sendMsgToWarehouse(odsOrder.getShopId().toString(), null);
                                } else if (odsOrder.getWarehouseId() != null){  // add by wg 20190717
                                    sendMsgToWarehouse(null, odsOrder.getWarehouseId().toString());
                                }
                            }
                        }
                        // mod by wg 20190516
//                    } else if (orderType.toString().substring(0, 1).equals("2")) {
                    } else if (params.get("body").equals("shopsend")) {
                        /**店铺购买
                         * 发货
                         * **/
                        System.out.println("shopsend");
                        List<Map> list = new ArrayList<>();
                        for (int i = 0; i < split.length; i++) {
                            OdsOrder odsOrder1 = odsOrderService.findById(Long.valueOf(split[i]));

                            // add by wg 20190711 增加货到付款处理
                            if (odsOrder1.getPayType() != 0) {
                                redisTemplate.delete("first:" + split[i]);
                            }

                            OdsOrder odsOrder = new OdsOrder();
                            odsOrder.setOrderId(Long.valueOf(split[i]));
                            odsOrder.setPayType((byte)2);  // add by wg 20190711
                            odsOrder.setPayStatus((byte) 1);
                            odsOrder.setPayTime(new Date());

                            // add by wg 20190711 增加货到付款处理
                            if (odsOrder1.getPayType() == 0) {  // 货到付款
                                odsOrder.setShippingStatus((byte) 3);
                                odsOrder.setOrderStatus((byte) 2);
                            } else {
                                odsOrder.setShippingStatus((byte) 0);
                                odsOrder.setOrderStatus((byte) 1);
                            }

                            if (odsOrder1 != null) {
                                odsOrder.setAmountPaid(odsOrder1.getAmountPayable());
                            } else {
                                // mod by wg 20190413
//                            double v = Double.parseDouble(total_amount) * 100;
                                double v = BigDecimalUtil.mul(Double.parseDouble(total_amount), 100).doubleValue();
                                odsOrder.setAmountPaid((int) v);
                            }

                            //保存到数据库，修改订单状态为已付款，未发货
                            //店铺预定，但是发货，已经减少了
                            // todo 目前对于返利结算直接在订单中优惠，因此此时直接将是否返利字段置为true，20190727
                            odsOrder.setIsCheckout(true);

                            odsOrderService.update(odsOrder);

                            //如果此单使用了优惠券，标记使用状态

                            if (null != odsOrder1 && null != odsOrder1.getCouponReceiveId()
                                    &&  null != odsOrder1.getCouponMoney()){
                                System.out.println("如果此单使用了优惠券，标记使用状态");
                                cmcFeignApi.updateCouponReceive(Long.valueOf(odsOrder1.getCouponReceiveId()),Long.valueOf(split[i]));
                            }

                            // add by wg 20190711 增加货到付款处理
                            if (odsOrder1.getPayType() != 0) {
                                String a = String.valueOf(odsOrder1.getShopId());
                                if (i == split.length - 1) {
                                    sb.append(a);
                                } else {
                                    sb.append(a + ",");
                                }
                            }
                        }

                        // add by wg 20190711 增加货到付款处理
                        if (PublicUtil.isNotEmpty(sb)) {
                            Map map = new HashMap();
                            map.put("MessageType", "findWarehouseAdmin");
                            map.put("shopIds", sb.toString());
                            map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
                            RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
                            rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
                            rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
                            rabbitMetaMessage.setPayload(JSON.toJSONString(map));
                            rabbitSender.send(rabbitMetaMessage);
                        }
                    }
                    // add by wg 20190711 增加货到付款处理
                    if (PublicUtil.isNotEmpty(sb)) {
                        Map map = new HashMap();
                        map.put("MessageType", "findWarehouseAdmin");
                        map.put("shopIds", sb.toString());
                        map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
                        RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
                        rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
                        rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
                        rabbitMetaMessage.setPayload(JSON.toJSONString(map));
                        rabbitSender.send(rabbitMetaMessage);
                    }


                }

                return "success";
            }
            // return "success";
            return "failure";
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }

    }

    private void sendMsgToWarehouse(String shopIds, String warehouseIds) {
        Map map = new HashMap();
        map.put("MessageType", "findWarehouseAdmin");
        map.put("shopIds", shopIds);
        map.put("warehouseIds", warehouseIds);
        map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
        RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
        rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
        rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
        rabbitMetaMessage.setPayload(JSON.toJSONString(map));
        try {
            rabbitSender.send(rabbitMetaMessage);
        } catch (Exception e) {
            log.error("rabbitSender.send()调用异常");
        }
    }

    /**
     * 订单退款
     *
     * @param
     * @param
     * @param
     * @param
     * @param
     */
    @RequestMapping(value = "/pay/refund", method = RequestMethod.POST)
    public int orderPayRefund(JSONObject jsonObject) {
        LOG.info("[/pay/refund]");
     /*   if (StringUtil.isEmpty(tradeno) && StringUtil.isEmpty(orderno)) {
            WebUtil.response(response, WebUtil.packJsonp(callback, JSON
                    .toJSONString(new JsonResult(-1, "订单号不能为空", new ResponseData()), SerializerFeatureUtil.FEATURES)));
        }*/
        Object orderId = jsonObject.get("orderId");
        Object out_trade_no = jsonObject.get("out_trade_no");
        Object refund_amount = jsonObject.get("refund_amount");
//        System.err.println(orderId);
//        System.err.println(refund_amount);
//        System.err.println();
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest(); // 统一收单交易退款接口
        // 只需要传入业务参数
        Map<String, Object> param = new HashMap<>();
        param.put("out_trade_no", out_trade_no); // 商户订单号
        param.put("refund_amount", refund_amount);// 退款金额
        param.put("refund_reason", "退款原因");// 退款原因
        param.put("out_request_no", "退款单号"); //退款单号
        alipayRequest.setBizContent(JSON.toJSONString(param)); // 不需要对json字符串转义

        Map<String, Object> restmap = new HashMap<>();// 返回支付宝退款信息
        boolean flag = false; // 查询状态
        try {
            AlipayTradeRefundResponse alipayResponse = Alipayutil.getAlipayClient().execute(alipayRequest);
            if (alipayResponse.isSuccess()) {
                // 调用成功，则处理业务逻辑
                if ("10000".equals(alipayResponse.getCode())) {
                    // 订单创建成功
                    flag = true;
                    LOG.info("订单退款结果：退款成功");
                    // todo 严格讲，结果只表明已经成功创建退款单，真正是否完成退款要在通知消息中才能确定，因此，后续操作应该在收到通知消息后才能处理
                    return 1;
                } else {
                    LOG.info("订单退款失败：" + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
                    return 0;
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return 0;
        }

        return 0;
    }

    /**
     * @param request
     * @param response
     * @param orderno  商家订单号
     * @param tradeno  支付宝订单号
     * @param callback
     */
    @RequestMapping(value = "/pay/refund/query", method = RequestMethod.POST)
    public void orderPayRefundQuery(HttpServletRequest request, HttpServletResponse response, String orderno,
                                    String tradeno, String callback) {
     /*   LOG.info("[/pay/refund/query]");
        if (StringUtil.isEmpty(orderno) && StringUtil.isEmpty(tradeno)) {
            WebUtil.response(response,
                    WebUtil.packJsonp(callback,
                            JSON.toJSONString(new JsonResult(-1, "商家订单号或支付宝订单号不能为空", new ResponseData()),
                                    SerializerFeatureUtil.FEATURES)));
        }*/

        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest(); // 统一收单交易退款查询
        // 只需要传入业务参数
        Map<String, Object> param = new HashMap<>();
        param.put("out_trade_no", orderno); // 商户订单号
        param.put("trade_no", tradeno);// 交易金额
        param.put("out_request_no", orderno);// 请求退款接口时，传入的退款请求号，如果在退款请求时未传入，则该值为创建交易时的外部交易号
        alipayRequest.setBizContent(JSON.toJSONString(param)); // 不需要对json字符串转义

        Map<String, Object> restmap = new HashMap<>();// 返回支付宝退款信息
        boolean flag = false; // 查询状态
        try {
            AlipayTradeFastpayRefundQueryResponse alipayResponse = Alipayutil.getAlipayClient().execute(alipayRequest);
            if (alipayResponse.isSuccess()) {
                // 调用成功，则处理业务逻辑
                if ("10000".equals(alipayResponse.getCode())) {
                    // 订单创建成功
                    flag = true;
                    restmap.put("out_trade_no", alipayResponse.getOutTradeNo());
                    restmap.put("trade_no", alipayResponse.getTradeNo());
                    restmap.put("out_request_no", alipayResponse.getOutRequestNo());// 退款订单号
                    restmap.put("refund_reason", alipayResponse.getRefundReason()); // 退款原因
                    restmap.put("total_amount", alipayResponse.getTotalAmount());// 订单交易金额
                    restmap.put("refund_amount", alipayResponse.getTotalAmount());// 订单退款金额
                    LOG.info("订单退款结果：退款成功");
                } else {
                    LOG.info("订单失败：" + alipayResponse.getMsg() + ":" + alipayResponse.getSubMsg());
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }


    }

    /**
     * 支付宝转账，主要用于平台向商户结算
     */

    //@RequestMapping(value = "/pay/transfer", method = RequestMethod.POST)
    @Async
    public Map transfer(Map<String, Object> map) {
        System.out.println("开始转账");
        AlipayClient alipayClient = Alipayutil.getAlipayClient();
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        Map<String, Object> map1 = new HashMap<String, Object>();

        //map1.put("out_biz_no", "3142321423432");
        map1.put("out_biz_no", odsOrderService.getsnowid());
        map1.put("payee_type", "ALIPAY_LOGONID");
        map1.put("payee_account", map.get("account_no"));
        map1.put("amount", map.get("totalmoney"));
        map1.put("remark", "转账");
        String s = JSON.toJSONString(map1);
        request.setBizContent(s);
       /* request.setBizContent("{" +
                "\"out_biz_no\":\"3142321423432\"," +
                "\"payee_type\":\"ALIPAY_LOGONID\"," +
                "\"payee_account\":\"abc@sina.com\"," +
                "\"amount\":\"12.23\"," +
                "\"payer_show_name\":\"上海交通卡退款\"," +
                "\"payee_real_name\":\"张三\"," +
                "\"remark\":\"转账备注\"" +
                "}");*/
        AlipayFundTransToaccountTransferResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
//            System.out.println("调用成功");
            if (response.getCode().equals("10000") || response.getCode().equals("PAYER_PAYEE_CANNOT_SAME")) {  // mod by wg 20190327 增加相同账号处理，如果自营，平台账号与店铺账号相同
//                System.out.println("转账成功");
                log.info("店铺结算成功");
                // mod by wg 20190411
//                String orderIds = map.get("orderIds").toString();
//                String substring = orderIds.substring(0, orderIds.lastIndexOf(","));
//                String[] split = substring.split(",");
//                for (int i = 0; i < split.length; i++) {
//                    OdsOrder odsOrder = new OdsOrder();
//                    odsOrder.setOrderId(Long.valueOf(split[i]));
//                    odsOrder.setIsCheckout(true);
//                    odsOrderService.update(odsOrder);
//                }

                JSONArray orderJsonArray = (JSONArray)map.get("orderIds");
                String strOrderIds = "";
                for (int i = 0; i < orderJsonArray.size(); i++) {
                    JSONObject orderJson = (JSONObject)orderJsonArray.get(i);
                    OdsOrder odsOrder = new OdsOrder();
                    odsOrder.setOrderId(orderJson.getLong("orderId"));
                    odsOrder.setIsCheckout(true);
                    odsOrder.setAmountCheckout(orderJson.getInteger("amountCheckout"));
                    // add by wg 20190727 同时改变订单状态
                    if ((byte)map.get("orderType") == 2) {
//                        odsOrder.setOrderStatus((byte)2); // 已完成
                        odsOrder.setShippingStatus((byte)3); // 已收货
                    }

                    odsOrderService.update(odsOrder);

                    strOrderIds += orderJson.get("orderId").toString();
                    if (i < orderJsonArray.size()-1) {
                        strOrderIds += ", ";
                    }
                }

                // 向用户发送消息
                if (map.get("orderType") != null) {
                    Byte orderType = (byte)map.get("orderType");
                    MsgNotificationBody msg = new MsgNotificationBody();

                    if (orderType == 1) {
                        msg.setOrderType((byte) 1);
                        msg.setTitle("结算转账通知");
                        msg.setContent("您店铺下的用户订单【" + strOrderIds + "】已经结算，总金额：" + map.get("totalmoney").toString() + "元，请查收！");
                    } else {
                        msg.setOrderType((byte) 2);
                        msg.setTitle("返利转账通知");
                        msg.setContent("您店铺下的进货订单【" + strOrderIds + "】已经返利，总金额：" + map.get("totalmoney").toString() + "元，请查收！");
                    }

                    msg.setTime(new Date());
                    msg.setReceiveType((byte) 3);
                    msg.setMsgType("orderMsg");
                    Long userId = (Long)map.get("userId");
                    opcSendNotifyFeignApi.sendnotify(userId.toString(), msg.getTitle(), msg.getContent(), 0);
                    opcSendNotifyFeignApi.sendnotify(userId.toString(), msg.getTitle(), JSON.toJSONString(msg), 1);
                }
            } else if (response.getCode().equals("20000")) {
                //当返回值为20000的时候，系统繁忙，调用查询接口,失败才调用查询接口，才会返回，成功不转账
                map.put("out_biz_no", map1.get("out_biz_no"));

                return map;
            }
        } else {
            System.out.println("调用失败");
        }
        return null;
    }

    public void queryTransfer(Map<String, String> map) {
        AlipayClient alipayClient = Alipayutil.getAlipayClient();
        AlipayFundTransOrderQueryRequest request = new AlipayFundTransOrderQueryRequest();
        Map<String, Object> map1 = new HashMap<String, Object>();
        map1.put("out_biz_no", map.get("out_biz_no"));
        String s = JSON.toJSONString(map1);
        request.setBizContent(s);
        AlipayFundTransOrderQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            if (response.getStatus().equals("SUCCESS")) {
                //查询转账成功，修改订单状态
                List<OdsOrder> all_order_id = payutil.updateit(map.get("all_order_id"));
                for (int i = 0; i < all_order_id.size(); i++) {
                    OdsOrder odsOrder1 = all_order_id.get(i);
                    odsOrder1.setIsCheckout(true);
                    // add by wg 20190727 同时改变订单状态
                    if (odsOrder1.getOrderType() == 2) {
//                        odsOrder1.setOrderStatus((byte)2); // 已完成
                        odsOrder1.setShippingStatus((byte)3); // 已收货
                    }

                    odsOrderService.update(odsOrder1);
                }
            }
        } else {
            System.out.println("调用失败");
        }

    }

    /**
     * 支付宝转账，主要用于店铺提现收益
     */
    @Async
    public int transferCommission(String accountNo, Integer amount) {
        AlipayClient alipayClient = Alipayutil.getAlipayClient();
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        Map<String, Object> map1 = new HashMap<String, Object>();

        double value = new BigDecimal(((double) amount) / 100).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();

        map1.put("out_biz_no", odsOrderService.getsnowid());
        map1.put("payee_type", "ALIPAY_LOGONID");
        map1.put("payee_account", accountNo);
        map1.put("amount", value);
        map1.put("remark", "转账");
        String s = JSON.toJSONString(map1);
        request.setBizContent(s);
        AlipayFundTransToaccountTransferResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return -1;
        }

        if (response.isSuccess()) {
            if (response.getCode().equals("10000") || response.getCode().equals("PAYER_PAYEE_CANNOT_SAME")) {  // mod by wg 20190327 增加相同账号处理，如果自营，平台账号与店铺账号相同
                log.info("店铺结算成功");
            } else if (response.getCode().equals("20000")) {
                //当返回值为20000的时候，系统繁忙，调用查询接口,失败才调用查询接口，才会返回，成功不转账
               log.warn("提现收益结算，支付系统繁忙！");
               // todo 需要处理
            }
        } else {
            log.error("提现收益结算，转账失败！");
            return -1;
        }

        return 0;
    }


}